package com.xianyun.rpc.loadBalance;

import cn.hutool.core.collection.CollUtil;
import com.xianyun.rpc.model.ServiceMetaInfo;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 强一致性 Hash 负载均衡
 * @author xianYun
 * @version 1.0
 **/
public class ConsistentHashLoadBalancer implements LoadBalancer{

    /**
     * 一致性 hash 环，用来存放虚拟节点
     */
    private final TreeMap<Integer, ServiceMetaInfo> ringMap = new TreeMap<>();

    /**
     * 虚拟节点数
     */
    private final int VIRTUAL_NODE_NUM = 100;

    @Override
    public ServiceMetaInfo select(Map<String, Object> requestParams, List<ServiceMetaInfo> serviceMetaInfoMap) {
        if (serviceMetaInfoMap.isEmpty()){
            return null;
        }

        //构建虚拟节点
        for (ServiceMetaInfo serviceMetaInfo : serviceMetaInfoMap) {
            for (int i = 0; i < VIRTUAL_NODE_NUM; i++) {
                String virtualNodeName = serviceMetaInfo.getServiceAddress() + "_VN" + i;
                int hash = getHash(virtualNodeName);
                ringMap.put(hash, serviceMetaInfo);
            }
        }
        int hash = getHash(requestParams);
        Map.Entry<Integer, ServiceMetaInfo> infoEntry = ringMap.ceilingEntry(hash);
        if (infoEntry == null) {
            infoEntry = ringMap.firstEntry();
        }
        return infoEntry.getValue();
    }

    private int getHash(Object key) {
        return key.hashCode();
    }
}
